package com.tx.core.mybatis.service;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.tx.core.mybatis.config.MybatisGlobalConfig;
import com.tx.core.paged.model.PagedList;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

/**
 * <pre>
 * 功能简述: 基础业务层接口定义
 * </pre>
 *
 * @author PengQingyang
 * 创建时间 [2024/3/31]
 */
public interface IBaseService<T, ID extends Serializable> {

    /**
     * 获取实体的类类型
     * <p>
     * 该方法不需要参数，它用于返回一个特定实体的类类型对象。
     * 通过这个方法，可以动态地获取到泛型T所代表的实体类，以便于进行进一步的操作，如实例化实体、查询实体属性等。
     *
     * @return 返回一个{@link Class<T>}对象，代表了泛型T的实体类。
     */
    Class<T> getEntityClass();

    /**
     * 创建一个新的实体对象实例
     *
     * @return 返回一个实体对象实例
     */
    T newEntityInstance();

    /**
     * 保存数据实体
     *
     * @param data 要保存的数据实体，类型为泛型 T
     * @@Transactional 注解表示该方法是一个事务方法，任何异常都会导致事务回滚
     */
    @Transactional(rollbackFor = Exception.class)
    void save(T data);

    /**
     * 保存数据实体的方法。
     * 这个方法会使用提供的数据实体和更新包装器函数来保存数据。如果数据存在，会根据更新包装器函数提供的逻辑进行更新；
     * 如果不存在，则进行插入。
     *
     * @param data                   需要保存的数据实体。
     * @param updateWrapperGenerator 一个函数，接受一个数据实体，返回一个对该实体进行更新操作的包装器。这个包装器用于
     *                               包装更新操作的逻辑。
     */
    @Transactional(rollbackFor = Exception.class)
    void save(T data, Function<T, Wrapper<T>> updateWrapperGenerator);

    /**
     * 批量保存对象
     *
     * @param dataList 要保存的对象列表，不应为空
     *                 <p>
     *                 注意：此方法为默认实现，提供了基本的批量保存逻辑，
     *                 可能会根据对象的数量和配置分批执行保存操作。
     */
    @Transactional(rollbackFor = Exception.class)
    default void batchSave(List<T> dataList) {
        batchSave(dataList, getDefaultBatchSize(), false);
    }

    /**
     * 批量保存对象
     *
     * @param dataList         要保存的对象列表
     * @param useBatchExecutor 是否使用批量执行器。当为true时，将使用批量执行策略来优化保存操作的性能。
     */
    @Transactional(rollbackFor = Exception.class)
    default void batchSave(List<T> dataList, boolean useBatchExecutor) {
        batchSave(dataList, getDefaultBatchSize(), useBatchExecutor);
    }

    /**
     * 批量保存对象
     *
     * @param dataList         要保存的对象列表，不应为空。
     * @param batchSize        每次保存的批大小。通过调整此参数，可以控制数据库操作的频率，以优化性能。
     * @param useBatchExecutor 是否使用批量执行器。当设置为true时，将使用批量执行器来优化批量保存的性能。
     */
    @Transactional(rollbackFor = Exception.class)
    void batchSave(List<T> dataList, int batchSize, boolean useBatchExecutor);

    /**
     * 批量保存对象
     *
     * @param dataList               要保存或更新的对象列表
     * @param updateWrapperGenerator 一个函数，接收一个对象，返回一个Wrapper，用于构造更新语句的条件
     */
    @Transactional(rollbackFor = Exception.class)
    default void batchSave(List<T> dataList, Function<T, Wrapper<T>> updateWrapperGenerator) {
        batchSave(dataList, updateWrapperGenerator, getDefaultBatchSize(), false);
    }

    /**
     * 批量保存对象
     *
     * @param dataList              需要保存或更新的数据对象列表
     * @param updateWrapperFunction 一个函数，用于为每个数据对象生成更新条件或查询Wrapper
     * @param useBatchExecutor      是否使用批量执行器来执行批量操作，通常与数据库的批量操作支持相关
     */
    @Transactional(rollbackFor = Exception.class)
    default void batchSave(List<T> dataList, Function<T, Wrapper<T>> updateWrapperFunction, boolean useBatchExecutor) {
        batchSave(dataList, updateWrapperFunction, getDefaultBatchSize(), useBatchExecutor);
    }

    /**
     * 批量保存对象
     *
     * @param dataList              需要保存或更新的数据对象列表
     * @param updateWrapperFunction 一个函数，用于为每个数据对象构建更新的条件包装器
     * @param batchSize             每次批量操作的大小
     * @param useBatchExecutor      是否使用批量执行器进行操作，这通常与数据库支持的批量操作相关
     */
    @Transactional(rollbackFor = Exception.class)
    void batchSave(List<T> dataList, Function<T, Wrapper<T>> updateWrapperFunction, int batchSize,
                   boolean useBatchExecutor);

    /**
     * 插入数据实体
     *
     * @param data 要插入的数据实体，类型为泛型 T
     */
    @Transactional(rollbackFor = Exception.class)
    // 标注为事务操作，任何异常都将导致回滚
    void insert(T data);

    /**
     * 批量插入数据到数据库。
     * 这个方法默认使用一个可配置的批处理大小和不执行前检查数据库连接的设置。
     *
     * @param dataList 要插入的数据列表，不应为空。
     */
    @Transactional(rollbackFor = Exception.class)
    default void batchInsert(List<T> dataList) {
        batchInsert(dataList, getDefaultBatchSize(), false);
    }

    /**
     * 批量插入数据到数据库。
     * 这个方法允许调用者指定是否使用批量执行器来优化插入性能，以及每次批量操作的默认大小。
     *
     * @param dataList         要插入的数据列表，不应为空。
     * @param useBatchExecutor 指定是否使用批量执行器。当为 true 时，将使用批量执行策略进行插入操作，以提高效率。
     */
    @Transactional(rollbackFor = Exception.class)
    default void batchInsert(List<T> dataList, boolean useBatchExecutor) {
        batchInsert(dataList, getDefaultBatchSize(), useBatchExecutor);
    }

    /**
     * 批量插入数据到数据库。
     * 该方法允许用户通过指定批量大小和是否使用批量执行器来优化数据插入性能。
     *
     * @param dataList         要插入的数据列表，不应为空。
     * @param batchSize        批量插入的大小，即每次提交到数据库的记录数。正值表示批量大小。
     * @param useBatchExecutor 指定是否使用批量执行器来执行插入操作。当为true时，将尝试使用更高效的批量执行策略。
     */
    @Transactional(rollbackFor = Exception.class)
    void batchInsert(List<T> dataList, int batchSize, boolean useBatchExecutor);

    /**
     * 根据主键删除数据
     * 此ID是指对应的表主键
     *
     * @param pk 被注解为@Id或@TableId的字段
     */
    @Transactional(rollbackFor = Exception.class)
    boolean deleteById(ID pk);

    /**
     * 根据实例删除对象
     * 本方法会根据传入的实体对象的值，删除数据库中对应的记录。
     *
     * @param entity 需要删除的实体对象。该对象应是本数据表的一个实例。
     * @return 返回删除操作影响的记录数。通常，如果删除成功，返回值应为1。
     */
    @Transactional(rollbackFor = Exception.class)
    int delete(T entity);

    /**
     * 批量删除数据的默认实现。
     * 这个方法会调用batchDelete(List<T> dataList, int batchSize, boolean force)的实现，使用默认的批处理大小和不强制执行的标志。
     *
     * @param dataList 要删除的数据列表。不应为空，否则可能导致运行时异常。
     */
    @Transactional(rollbackFor = Exception.class)
    default void batchDelete(List<T> dataList) {
        batchDelete(dataList, getDefaultBatchSize(), false);
    }

    /**
     * 批量删除数据的默认实现。
     *
     * @param dataList         要删除的数据列表，不应为空。
     * @param useBatchExecutor 指定是否使用批量执行器。如果为true，则会尝试使用批量执行策略进行删除。
     */
    @Transactional(rollbackFor = Exception.class)
    default void batchDelete(List<T> dataList, boolean useBatchExecutor) {
        batchDelete(dataList, getDefaultBatchSize(), useBatchExecutor);
    }

    /**
     * 批量删除数据的函数。
     * 这个方法会根据提供的数据列表、批量大小和是否使用批量执行器的标志来删除数据。
     *
     * @param dataList         要删除的数据列表，不应为空。
     * @param batchSize        每次删除操作处理的数据条数。
     * @param useBatchExecutor 是否使用批量执行器来执行删除操作。如果为true，则使用批量执行策略；如果为false，可能按常规单条删除方式执行。
     */
    @Transactional(rollbackFor = Exception.class)
    void batchDelete(List<T> dataList, int batchSize, boolean useBatchExecutor);

    /**
     * 根据ID更新数据
     * 注：在mybatis-plus的实现中，不支持将字段设置为null，
     * 如果需要将字段设置为null，请调用基于Wrapper的updateById实现。
     *
     * @param id     数据的唯一标识符
     * @param entity 要更新的数据实体
     * @return 如果更新成功返回true，否则返回false
     */
    @Transactional(rollbackFor = Exception.class)
    boolean updateById(ID id, T entity);

    /**
     * 更新指定实体的主键。
     *
     * @param entity 需要更新的实体对象，该实体对象的类型由调用者指定。
     * @return 更新成功后的实体影响行数，通常为1表示更新成功。
     */
    @Transactional(rollbackFor = Exception.class)
    int update(T entity);

    /**
     * 更新指定实体的主键。
     *
     * @param id      主键，用于指定要更新的实体。
     * @param entity  要更新的实体对象。
     * @param wrapper 更新条件，用于指定更新哪些字段。
     * @return 更新成功后的实体影响行数，通常为1表示更新成功。
     */
    @Transactional(rollbackFor = Exception.class)
    boolean updateById(ID id, T entity, Wrapper<T> wrapper);

    /**
     * 更新指定实体的主键。
     *
     * @param entity  要更新的实体对象。
     * @param wrapper 更新条件，用于指定更新哪些字段。
     * @return 更新成功后的实体影响行数，通常为1表示更新成功。
     */
    @Transactional(rollbackFor = Exception.class)
    int update(T entity, Wrapper<T> wrapper);

    /**
     * 更新主键对应的实体信息。
     * 本方法会根据提供的实体ID和实体对象，使用提供的函数式接口生成更新条件，然后执行更新操作。
     *
     * @param id                     主键，用于指定要更新的实体。
     * @param entity                 要更新的实体对象。
     * @param updateWrapperGenerator 一个函数式接口，用于生成更新条件的Wrapper。该函数接收一个实体对象，返回一个对应该实体的更新条件Wrapper。
     * @return 更新操作是否成功。成功返回true，失败返回false。
     */
    @Transactional(rollbackFor = Exception.class)
    boolean updateById(ID id, T entity, Function<T, Wrapper<T>> updateWrapperGenerator);

    /**
     * 更新主键对应的实体信息。
     * 本方法会根据提供的实体对象和更新生成器，来构造更新语句并执行更新操作。
     *
     * @param entity                 需要更新的实体对象，其主键将被用于确定更新的目标记录。
     * @param updateWrapperGenerator 一个函数接口，用于根据输入实体生成更新语句的包装器。这允许动态构造更新逻辑。
     * @return 返回更新操作影响的行数，通常为1，如果未影响任何行，则可能表示更新前的实体状态与数据库中的状态不一致。
     */
    @Transactional(rollbackFor = Exception.class)
    int update(T entity, Function<T, Wrapper<T>> updateWrapperGenerator);

    /**
     * 批量更新实体
     *
     * @param entityList 要进行批量更新的实体列表
     *                   注意：此方法为默认实现，提供了基本的批量更新逻辑，
     *                   可通过调用batchUpdate(List<T> entityList, int batchSize, boolean flush)方法进行更细致的控制。
     */
    @Transactional(rollbackFor = Exception.class)
    default void batchUpdate(List<T> entityList) {
        batchUpdate(entityList, getDefaultBatchSize(), false);
    }

    /**
     * 批量更新实体
     *
     * @param entityList       需要更新的实体列表
     * @param useBatchExecutor 是否使用批量执行器。如果为true，则会使用批量执行器来执行更新操作，以提高效率。
     */
    @Transactional(rollbackFor = Exception.class)
    default void batchUpdate(List<T> entityList, boolean useBatchExecutor) {
        batchUpdate(entityList, getDefaultBatchSize(), useBatchExecutor);
    }

    /**
     * 批量更新实体
     *
     * @param entityList       需要更新的实体列表
     * @param batchSize        每次批量操作的大小
     * @param useBatchExecutor 是否使用批量执行器进行更新
     */
    @Transactional(rollbackFor = Exception.class)
    void batchUpdate(List<T> entityList, int batchSize, boolean useBatchExecutor);

    /**
     * 批量更新接口方法
     *
     * @param entityList             需要更新的实体列表，不应为空。
     * @param updateWrapperGenerator 一个函数接口，用于为每个实体生成更新条件的Wrapper。该函数接收一个实体T作为参数，返回一个针对该实体的更新条件Wrapper<T>。
     * @see Function 接口用于定义函数式接口，此处作为生成更新条件的策略。
     */
    default void batchUpdate(List<T> entityList, Function<T, Wrapper<T>> updateWrapperGenerator) {
        batchUpdate(entityList, updateWrapperGenerator, getDefaultBatchSize(), false);
    }

    /**
     * 批量更新方法
     *
     * @param entityList             需要更新的实体列表，不应为空。
     * @param updateWrapperGenerator 一个函数接口，用于根据实体生成更新条件包装器。该包装器定义了如何选择要更新的记录。
     * @param useBatchExecutor       是否使用批量执行器。当设置为true时，将使用批量执行策略，可能提高更新效率。
     */
    default void batchUpdate(List<T> entityList, Function<T, Wrapper<T>> updateWrapperGenerator,
                             boolean useBatchExecutor) {
        batchUpdate(entityList, updateWrapperGenerator, getDefaultBatchSize(), useBatchExecutor);
    }


    /**
     * 批量更新实体列表。
     *
     * @param entityList             需要更新的实体列表，不应为空。
     * @param updateWrapperGenerator 一个函数接口，用于根据实体生成更新条件包装器。该包装器定义了如何选择要更新的记录。
     * @param batchSize              每次数据库交互更新的实体数量。批量大小决定了更新操作的分批方式。
     * @param useBatchExecutor       是否使用批量执行器来执行更新。当设置为true时，将使用更高效的批量执行策略。
     */
    @Transactional(rollbackFor = Exception.class)
    void batchUpdate(List<T> entityList, Function<T, Wrapper<T>> updateWrapperGenerator, int batchSize,
                     boolean useBatchExecutor);


    /**
     * 根据主键查询实体对象。
     * 这个方法通过给定的主键值来检索数据库中对应的实体对象。主键字段是被注解为@Id或@TableId的字段。
     *
     * @param pk 主键，实体对象的唯一标识符。
     * @return 返回类型为T的实体对象，如果找不到对应实体，则返回null。
     */
    T findById(ID pk);

    /**
     * 查询方法
     *
     * @param entity 查询条件实体对象，用于构建查询条件。
     * @return 返回一个包含查询结果的列表。
     */
    T find(T entity);

    /**
     * 分页查询方法
     * <p>
     * 通过传入查询参数、页码和每页大小，来获取对应页的查询结果列表。
     *
     * @param params    查询参数，以键值对形式传入，用于构建查询条件。
     * @param pageIndex 请求的页码，第一页为0。
     * @param pageSize  每页显示的记录数。
     * @return 返回一个PagedList对象，包含当前页的查询结果列表和其他分页相关信息。
     */
    PagedList<T> queryPagedList(Map<String, Object> params,
                                int pageIndex, int pageSize);


    /**
     * 分页查询方法
     *
     * @param params    查询参数，以键值对形式提供
     * @param pageIndex 请求的页码，第几页，从1开始计数
     * @param pageSize  每页的记录数
     * @param count     总记录数，用于计算总页数
     * @return 返回一个PagedList对象，包含当前页的记录列表
     */
    PagedList<T> queryPagedList(Map<String, Object> params,
                                int pageIndex, int pageSize, int count);


    /**
     * 分页查询方法的默认实现。
     *
     * @param wrapper   查询条件包装对象，用于指定查询的条件。
     * @param pageIndex 请求的页码，表示需要获取第几页的数据。
     * @param pageSize  每页的大小，表示每页包含的数据条数。
     * @return 返回一个PagedList对象，其中包含了查询结果的分页信息和数据。
     */
    default PagedList<T> queryPagedList(Wrapper<T> wrapper,
                                        int pageIndex, int pageSize) {
        // 调用另一个重载的queryPagedList方法，通过传递null来处理分页查询
        return queryPagedList(wrapper, null, pageIndex, pageSize);
    }


    /**
     * 分页查询方法
     *
     * @param wrapper   查询条件包装对象，用于指定查询的详细条件
     * @param params    查询参数，封装了各种查询所需要的具体参数
     * @param pageIndex 请求的页码，表示需要获取第几页的数据
     * @param pageSize  每页显示的记录数
     * @return 返回一个PagedList<T>对象，其中包含了查询结果的分页信息和数据
     */
    PagedList<T> queryPagedList(Wrapper<T> wrapper, Map<String, Object> params,
                                int pageIndex, int pageSize);


    /**
     * 分页查询方法的默认实现。
     *
     * @param wrapper   查询条件包装对象，用于指定查询的条件。
     * @param pageIndex 请求的页码，表示需要获取第几页的数据。
     * @param pageSize  每页的大小，表示每页包含的数据条数。
     * @param count     总数据条数，用于分页计算时使用。
     * @return 返回一个PagedList对象，包含了分页查询的结果。
     */
    default PagedList<T> queryPagedList(Wrapper<T> wrapper,
                                        int pageIndex, int pageSize, int count) {
        // 调用另一个重载的queryPagedList方法，进行分页查询
        return queryPagedList(wrapper, null, pageIndex, pageSize, count);
    }


    /**
     * 分页查询方法
     * 用于根据给定的查询条件、分页信息执行查询，并返回分页结果。
     *
     * @param wrapper   查询条件包装对象，用于指定查询的条件。
     * @param params    查询参数，包含查询中需要的额外参数。
     * @param pageIndex 请求的页码，表示需要获取的页的索引。
     * @param pageSize  每页的大小，表示每页包含的记录数量。
     * @param count     总记录数，用于分页计算，可以为0或负数，表示未统计总记录数。
     * @return 返回分页列表对象，包含当前页的记录列表。
     */
    PagedList<T> queryPagedList(Wrapper<T> wrapper, Map<String, Object> params,
                                int pageIndex, int pageSize, int count);


    /**
     * 查询列表的通用方法，根据提供的参数映射进行查询，并返回查询结果列表。
     *
     * @param params 用于查询的参数映射，键值对形式，具体依赖于实际查询需求。
     * @return 返回查询结果的列表，列表元素类型为泛型 T。
     */
    List<T> queryList(Map<String, Object> params);

    /**
     * 查询列表的默认实现。
     * 该方法接受一个查询条件包装器和一个可选的参数，然后返回一个查询结果列表。
     * 如果提供了第二个参数，它可能会被用于进一步定制查询行为，但在当前的默认实现中，该参数被允许为null。
     *
     * @param wrapper 查询条件包装器，用于指定查询的条件。
     * @return 返回一个查询结果的列表，列表的元素类型为泛型T。
     */
    default List<T> queryList(Wrapper<T> wrapper) {
        return queryList(wrapper, null);
    }


    /**
     * 查询列表。该方法用于根据提供的条件查询列表数据。
     *
     * @param wrapper 查询条件包装对象，用于指定查询的详细条件。
     * @param params  查询参数映射，用于传递查询中可能用到的参数。
     * @return 返回查询结果列表，列表的类型为泛型 T。
     */
    List<T> queryList(Wrapper<T> wrapper, Map<String, Object> params);


    /**
     * 根据条件查询对象实例数量<br/>
     * 该方法提供了一个通用的计数接口，可以根据传入的参数条件查询特定对象的实例数量。
     *
     * @param params 查询条件参数，以键值对的形式传入，具体的键值对取决于查询需求。
     * @return 返回查询到的实例数量，类型为int。
     */
    default int count(Map<String, Object> params) {
        return count(params, null);
    }


    /**
     * 根据条件查询对象实例数量
     * 该方法用于根据提供的参数和排除条件，查询满足条件的对象实例数量。
     *
     * @param params  用于查询条件的参数集合，键值对形式，具体根据实际查询需要设定。
     * @param exclude 排除条件，指定ID的对象将不被计入查询结果中。
     * @return 返回满足查询条件的对象实例数量，类型为int。
     */
    int count(Map<String, Object> params, ID exclude);

    /**
     * 根据条件查询对象实例数量<br/>
     * 本方法是一个默认方法，提供了一个简化的条件查询计数接口。<br/>
     * 通过给定的条件包装器（Wrapper）来指定查询条件，返回符合条件的对象实例数量。<br/>
     *
     * @param wrapper 查询条件的包装器，用于指定查询的条件。
     * @return 返回符合条件的对象实例的数量。
     */
    default int count(Wrapper<T> wrapper) {
        return count(wrapper, null, null);
    }


    /**
     * 根据条件查询对象实例数量<br/>
     * 该方法是默认方法，提供了一个简化版的条件查询计数接口，它允许你排除特定ID的实例。
     *
     * @param wrapper 查询条件，用于构建查询条件的包装器对象
     * @param exclude 排除的ID，此ID的实例将不被包含在查询结果中
     * @return 符合条件的对象实例数量
     */
    default int count(Wrapper<T> wrapper, ID exclude) {
        return count(wrapper, null, exclude);
    }

    /**
     * 根据条件查询对象实例数量<br/>
     * 本方法通过给定的条件包装器（Wrapper）和参数映射（Map）查询特定条件下的对象实例数量。
     * 如果需要，还可以通过第三个参数传递额外的查询选项，尽管本方法的实现不直接使用它。
     *
     * @param wrapper 用于构建查询条件的Wrapper对象
     * @param params  包含查询所需参数的映射
     * @return 符合条件的对象实例数量
     */
    default int count(Wrapper<T> wrapper, Map<String, Object> params) {
        return count(wrapper, params, null);
    }

    /**
     * 根据条件查询对象实例数量<br/>
     * 该方法用于根据提供的条件查询特定对象的实例数量。可以排除特定ID的实例。
     *
     * @param wrapper 查询条件，用于构建查询条件的包装器对象。
     * @param params  可选参数映射，可用于进一步定制查询条件。
     * @param exclude 需要排除的ID，即在计数时不考虑该ID对应的实例。
     * @return int 返回符合条件的对象实例数量。
     */
    int count(Wrapper<T> wrapper, Map<String, Object> params, ID exclude);

    /**
     * 判断指定条件的对象实例是否存在
     * <br/>
     * 根据提供的参数映射，检查满足条件的实例数量，并确定是否存在满足条件的实例。
     *
     * @param params 包含查询条件的键值对映射。这里的参数具体依赖于实际的查询需求和实现。
     * @return boolean 返回true如果存在至少一个满足条件的实例，否则返回false。
     */
    default boolean exist(Map<String, Object> params) {
        // 根据条件查询实例数量
        int count = count(params);
        // 如果数量大于0，则表示存在满足条件的实例
        return count > 0;
    }

    /**
     * 判断指定条件的对象实例是否存在<br/>
     * 通过传入的参数条件和排除的ID，检查数据库中是否存在满足条件的记录。
     *
     * @param params  包含查询条件的键值对参数集合
     * @param exclude 需要排除的ID，即在查询条件中不包括此ID的对象
     * @return 返回一个布尔值，如果存在满足条件的记录则返回true，否则返回false
     */
    default boolean exist(Map<String, Object> params, ID exclude) {
        // 根据条件查询记录的数量
        int count = count(params, exclude);
        // 如果查询到的记录数量大于0，表示存在满足条件的记录
        return count > 0;
    }

    /**
     * 判断指定条件的对象实例是否存在
     * <br/>
     * 通过给定的Wrapper条件，查询满足条件的对象数量，如果数量大于0，则表示存在满足条件的对象。
     *
     * @param wrapper 包含查询条件的Wrapper对象，用于指定查询的条件
     * @return boolean 返回true表示存在满足条件的对象，false表示不存在或查询条件为空
     */
    default boolean exist(Wrapper<T> wrapper) {
        int count = count(wrapper); // 计算满足wrapper条件的对象数量
        return count > 0; // 如果数量大于0，则表示存在满足条件的对象
    }

    /**
     * 判断对象是否存在
     *
     * @param wrapper   用于查询条件的包装器，封装了查询的具体条件
     * @param excludeId 要排除的ID，即在判断存在性时，不考虑此ID对应的对象
     * @return 返回对象是否存在的布尔值，如果存在返回true，否则返回false
     */
    default boolean exist(Wrapper<T> wrapper, ID excludeId) {
        // 根据wrapper条件和excludeId查询对象数量
        int count = count(wrapper, excludeId);
        // 判断查询到的数量是否大于0，大于0表示存在，否则表示不存在
        return count > 0;
    }

    /**
     * 判断指定条件的对象实例是否存在
     * <br/>
     * 通过给定的条件包装器（Wrapper）和参数映射（Map），查询满足条件的记录数，
     * 并根据记录数判断指定条件的对象实例是否存在。
     *
     * @param wrapper 条件包装器，用于指定查询条件
     * @param params  参数映射，用于传递查询所需的参数
     * @return boolean 返回true如果存在满足条件的实例，否则返回false
     */
    default boolean exist(Wrapper<T> wrapper, Map<String, Object> params) {
        // 根据条件查询记录数
        int count = count(wrapper, params);
        // 判断记录数是否大于0，以确定实例是否存在
        return count > 0;
    }

    /**
     * 判断指定条件的对象实例是否存在
     * <p>
     * 通过给定的条件包装器（Wrapper）和参数（params）来查询数据库中符合条件的记录数量，
     * 如果排除ID（exclude）被提供，则不计算此ID对应的记录。
     * 根据查询结果的数量判断对象实例是否存在。
     *
     * @param wrapper 条件包装器，用于构建查询条件
     * @param params  包含查询参数的映射，用于动态构建查询条件
     * @param exclude 需要排除的ID，可选参数，用于确保查询结果不包括特定ID的记录
     * @return boolean 返回true如果存在至少一个符合条件的记录，否则返回false
     */
    default boolean exist(Wrapper<T> wrapper, Map<String, Object> params, ID exclude) {
        int count = count(wrapper, params, exclude); // 计算符合条件的记录数量
        return count > 0;
    }

    /**
     * 判断指定条件的对象实例是否唯一
     * 通过传入的参数映射，查询满足条件的记录数，以判断对象实例是否唯一
     *
     * @param params 包含查询条件的键值对映射
     * @return 返回一个布尔值，如果查询到的记录数为1，则返回true，表示唯一；如果记录数为0，返回null，表示不存在满足条件的记录；如果记录数大于1，返回false，表示不唯一。
     */
    default Boolean unique(Map<String, Object> params) {
        // 根据传入的参数计算满足条件的记录数
        int count = count(params);
        // 判断记录数是否为1，以确定对象实例是否唯一
        boolean flag = count == 1;
        // 根据记录数返回相应的布尔值，true表示唯一，null表示不存在该记录，false表示不唯一
        return count == 1 ? true : count == 0 ? null : false;
    }

    /**
     * 判断指定条件的对象实例是否唯一<br/>
     * 该方法通过给定的条件（封装在Wrapper对象中）来查询对象实例的数量，进而判断是否唯一。<br/>
     * 如果查询到的数量为1，则认为条件下的实例是唯一的；如果查询到的数量为0，表示没有找到符合条件的实例；<br/>
     * 如果查询到的数量大于1，则表示条件下有多个实例，不是唯一的。
     *
     * @param wrapper 包含查询条件的Wrapper对象，用于指定查询的条件。
     * @return 返回一个布尔值，如果符合条件的实例唯一，则返回true；如果不存在符合条件的实例，则返回null；如果存在多个符合条件的实例，则返回false。
     */
    default Boolean unique(Wrapper<T> wrapper) {
        int count = count(wrapper); // 根据条件查询符合条件的实例数量
        return count == 1 ? true : count == 0 ? null : false; // 根据数量判断实例是否唯一
    }

    /**
     * 判断指定条件的对象实例是否唯一<br/>
     * 通过给定的条件（封装在Wrapper中）和参数（Map形式），查询数据库中满足条件的记录数，
     * 从而判断是否存在唯一的记录。<br/>
     * 如果记录数为1，则认为条件下的实例是唯一的；如果记录数为0，表示没有找到符合条件的记录，
     * 对于这种情况，本方法返回null；如果记录数大于1，表示存在多个符合条件的记录，
     * 则认为实例不是唯一的。<br/>
     * <功能详细描述>
     *
     * @param wrapper 用于封装查询条件的对象
     * @param params  包含查询参数的Map
     * @return 如果查询结果唯一则返回true，如果没有找到记录则返回null，否则返回false
     */
    default Boolean unique(Wrapper<T> wrapper, Map<String, Object> params) {
        int count = count(wrapper, params); // 计算满足条件的记录数
        return count == 1 ? true : count == 0 ? null : false; // 根据记录数判断实例是否唯一
    }

    /**
     * 获取批处理量
     * 通过重载该方法，可以实现每个对象的批量提交量不同
     *
     * @return 获取批处理量
     */
    default int getDefaultBatchSize() {
        return MybatisGlobalConfig.DEFAULT_DO_FLUSH_SIZE;
    }
}
